home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / TurboTCP 1.0.1 / Aliases / About box classes / CAboutDialog.cp next >
Encoding:
Text File  |  1993-12-10  |  9.5 KB  |  400 lines  |  [TEXT/KAHL]

  1. /*
  2. ** CAboutDialog.cp
  3. **
  4. **    About box library
  5. **    Dialog box class
  6. **
  7. **    Copyright © 1993, FrostByte Design / Eric Scouten
  8. **
  9. */
  10.  
  11.  
  12. #include "CAboutDialog.h"
  13.  
  14. #include <Global.h>
  15. #include <TBUtilities.h>
  16. #include <CEditText.h>
  17. #include <CPicture.h>
  18. #include <string.h>
  19.  
  20. #define HiNibble(_byte) ((_byte) >> 4)
  21. #define LoNibble(_byte) ((_byte) & 0x0F)
  22.  
  23.  
  24. //    —— initialization ——
  25.  
  26. /*______________________________________________________________________
  27. **
  28. ** IAboutDialog
  29. **
  30. **    Initialize the dialog. Nothing special here.
  31. **
  32. **        DLOGid (short):                the resource ID
  33. **        anEnclosure (CDesktop *):        the enclosure for the view
  34. **        aSupervisor (CDirector *):    the view’s supervisor in the chain of command
  35. **
  36. */
  37.  
  38. void CAboutDialog::IAboutDialog (short DLOGid, CDesktop *anEnclosure, CDirector *aSupervisor)
  39.  
  40. {
  41.     IDLOGDialog(DLOGid, anEnclosure, aSupervisor);
  42. }
  43.  
  44.  
  45. //    —— special text handling functions ——
  46.  
  47. /*______________________________________________________________________
  48. **
  49. ** AddDITLStatText
  50. **
  51. **    Add a static text item. Responds to standard overloaded text items. Also checks for
  52. **    the following special characters to be included in about box text:
  53. **
  54. **
  55. **        aWidth (short):            width of static text item
  56. **        aHeight (short):        height
  57. **        hEncl (short):            position within enclosing frame
  58. **        vEncl (short):                 ""            ""
  59. **        enclosure (CView *):    enclosing frame
  60. **        ditlItem (tDITLItem *):    the DITL item pointer
  61. **
  62. **        return (CPane *):        the item which was created
  63. **
  64. */
  65.  
  66. CPane *CAboutDialog::AddDITLStatText (short aWidth, short aHeight, short hEncl,
  67.                                 short vEncl, CView *enclosure, tDITLItem *ditlItem)
  68.  
  69. {
  70.     CEditText        *text;
  71.     unsigned char    length;
  72.     short        index;
  73.     Str255        itemText;
  74.     Str255        itemText2;
  75.     Str255        tempStr;
  76.  
  77.  
  78.     // first check for overloaded item (signaled by '@' in first position)
  79.  
  80.     if (ditlItem->itemLength != 0 && (* (char*) ditlItem->itemData) == '@') {
  81.         length = Min(ditlItem->itemLength-1, 255);
  82.         BlockMove(((char*) ditlItem->itemData)+1, &itemText[1], length);
  83.         itemText[0] = length;
  84.         return (AddOverloadedItem(itemText, aWidth, aHeight, hEncl, vEncl,
  85.                             enclosure, ditlItem));
  86.     }
  87.     else {
  88.     
  89.         // not overloaded, handle it normally
  90.  
  91.         text = new (CEditText);
  92.         text->IEditText(enclosure, this, aWidth, aHeight, hEncl, vEncl,
  93.                     sizFIXEDSTICKY, sizFIXEDSTICKY, -1);
  94.         text->Specify(kNotEditable, kNotSelectable, kNotStylable);
  95.         text->SetFontNumber(staticTextFont);
  96.         if (staticTextSize > 0)
  97.             text->SetFontSize(staticTextSize);
  98.         if (ditlItem->itemLength) {
  99.         
  100.             // check text for special symbols
  101.  
  102.             length = Min(ditlItem->itemLength, 255);
  103.             BlockMove(((char*) ditlItem->itemData), &itemText[1], length);
  104.             itemText[0] = length;
  105.             itemText2[0] = 0;
  106.             index = 1;
  107.  
  108.             while (index < length) {
  109.                 CollectUntilHiBit(itemText, &index, tempStr);
  110.                 ConcatPStrings(itemText2, tempStr);
  111.                 if (index < length) {
  112.                     ExpandHiBit(itemText[index], tempStr);
  113.                     ConcatPStrings(itemText2, tempStr);
  114.                 }
  115.                 index++;
  116.             }
  117.             
  118.             text->SetTextPtr((Ptr) &(itemText2[1]), itemText2[0]);
  119.         }
  120.         return (text);
  121.     }
  122.  
  123. }
  124.  
  125.  
  126. /*______________________________________________________________________
  127. **
  128. ** AddDITLPicture
  129. **
  130. **    Add a picture item to the dialog. Overriden to substitute PICT+1 when on a black & white
  131. **    screen.
  132. **
  133. **        itemText (StringPtr):    the text of the item
  134. **        aWidth (short):            width of static text item
  135. **        aHeight (short):        height
  136. **        hEncl (short):            position within enclosing frame
  137. **        vEncl (short):                 ""            ""
  138. **        enclosure (CView *):    enclosing frame
  139. **        ditlItem (tDITLItem *):    the DITL item pointer
  140. **
  141. **        return (CPane *):        the item which was created
  142. **
  143. */
  144.  
  145. CPane *CAboutDialog::AddDITLPicture (short aWidth, short aHeight, short hEncl,
  146.                                 short vEncl, CView *enclosure, tDITLItem *ditlItem)
  147. {
  148.     CPicture    *pict = new (CPicture);
  149.     short    depth;
  150.     short    pictID;
  151.     GDHandle    theDevice;
  152.  
  153.  
  154.     // determine pixel depth of main screen (where about box theoretically is…)
  155.  
  156.     depth = 1;
  157.     if (IsColor()) {
  158.         theDevice = GetMainDevice();
  159.         depth = (**((**theDevice).gdPMap)).pixelSize;
  160.     }
  161.  
  162.  
  163.     // choose which PICT we’ll use
  164.  
  165.     pictID = ditlItem->itemData[0];
  166.     if ((depth < 4) && (GetResource('PICT', pictID+1) != NULL))
  167.         pictID++;
  168.  
  169.  
  170.     // create the picture element for it
  171.  
  172.     pict->IPicture(enclosure, this, aWidth, aHeight, hEncl, vEncl, sizFIXEDSTICKY, sizFIXEDSTICKY);
  173.     pict->UsePICT(pictID);
  174.     return (pict);
  175.  
  176. }
  177.  
  178.  
  179. /*______________________________________________________________________
  180. **
  181. ** AddOverloadedItem
  182. **
  183. **    Override the default overloaded item handler to provide font-changing behavior.
  184. **    Recognizes strings of the form "@~<font name>~<font size>".
  185. **
  186. **        itemText (StringPtr):    the text of the item
  187. **        aWidth (short):            width of static text item
  188. **        aHeight (short):        height
  189. **        hEncl (short):            position within enclosing frame
  190. **        vEncl (short):                 ""            ""
  191. **        enclosure (CView *):    enclosing frame
  192. **        ditlItem (tDITLItem *):    the DITL item pointer
  193. **
  194. **        return (CPane *):        the item which was created
  195. **
  196. */
  197.  
  198. CPane *CAboutDialog::AddOverloadedItem (StringPtr itemText, short aWidth, short aHeight, 
  199.                                     short hEncl, short vEncl, CView *enclosure,
  200.                                     tDITLItem *ditlItem)
  201.  
  202. {
  203.     short    index;
  204.     Str255    localText;
  205.     Str255    fontName;
  206.     Str255    fontSize;
  207.     short    fontNum;
  208.     long        fontSizeNum;
  209.  
  210.  
  211.     BlockMove(itemText, localText, 256);            // prevent memory shuffle problems
  212.     if (localText[1] == '~') {
  213.     
  214.         // get font name, size
  215.  
  216.         PtoCstr(localText);
  217.         index = strchr((char *) &localText[1], '~') - (char *) &localText[1];
  218.         if ((index < 0) || (index > 254)) {
  219.             CtoPstr((char *) localText);
  220.             return NULL;                        // ignore this one
  221.         }
  222.         strncpy((char *) fontName, (char *) &localText[1], index);
  223.         fontName[index] = '\0';                    // don’t ask me why…
  224.         strcpy((char *) fontSize, (char *) &localText[index+2]);
  225.         CtoPstr((char *) fontName);
  226.         CtoPstr((char *) fontSize);
  227.         CtoPstr((char *) localText);
  228.         
  229.         
  230.         // convert strings to usable numbers
  231.         
  232.         GetFontNumber(fontName, &fontNum);
  233.         StringToNum(fontSize, &fontSizeNum);
  234.         
  235.         if (fontNum >= 0) {                        // allow two sequential strings to dictate font preference
  236.             staticTextFont = fontNum;
  237.             staticTextSize = (short) fontSizeNum;
  238.         }
  239.  
  240.         return NULL;                            // no item created
  241.  
  242.     }
  243.  
  244.     else
  245.         return (CDLOGDialog::AddOverloadedItem(localText, aWidth, aHeight, hEncl,
  246.                                         vEncl, enclosure, ditlItem));
  247.  
  248. }
  249.  
  250.  
  251. //    —— utility procedures ——
  252.  
  253. /*______________________________________________________________________
  254. **
  255. ** CollectUntilHiBit (protected method)
  256. **
  257. **    Collect characters from a string until a character is found with the high bit set.
  258. **
  259. **        text (StringPtr):        pointer to the source string
  260. **        index (short *):        where are we in the source string?
  261. **        returnStr (StringPtr):    where to send the collected text
  262. **
  263. */
  264.  
  265. void CAboutDialog::CollectUntilHiBit (StringPtr text, short *index, StringPtr returnStr)
  266.  
  267. {
  268.     short    i = *index;
  269.     short    limit = Length(text);
  270.     
  271.     Length(returnStr) = 0;
  272.     while (((text[i] & 0x80) == 0) && (i <= limit))
  273.         returnStr[++returnStr[0]] = text[i++];
  274.  
  275.     if (i > limit)
  276.         i = limit;
  277.     *index = i;
  278. }
  279.  
  280.  
  281. /*______________________________________________________________________
  282. **
  283. ** ExpandHiBit (protected method)
  284. **
  285. **    Expand a special character with the high bit set. Responds to the following characters:
  286. **
  287. **        character            replace with
  288. **        -----------        ---------------
  289. **        √ (option-V)        current version number (see GetVersion)
  290. **
  291. **
  292. **        theChar (unsigned char):    the character to expand
  293. **        returnStr (StringPtr):    where to return the expanded string
  294. **
  295. */
  296.  
  297. void CAboutDialog::ExpandHiBit (unsigned char theChar, StringPtr returnStr)
  298.  
  299. {
  300.     switch (theChar) {
  301.  
  302.         case (unsigned char) '√':
  303.             GetVersion (1, returnStr);
  304.             break;
  305.         
  306.         default:
  307.             returnStr[0] = 1;                // just send the character back as a string
  308.             returnStr[1] = theChar;
  309.     }
  310.  
  311. }
  312.  
  313.  
  314. /*______________________________________________________________________
  315. **
  316. ** GetVersion (protected method)
  317. **
  318. **    Get the version number from the 'vers' resource and format it as a text version string.
  319. **
  320. **        versID (short):        the 'vers' resource to read
  321. **        theString (Str255):    where to return the text
  322. **
  323. */
  324.  
  325. void CAboutDialog::GetVersion (short versID, Str255 theString)
  326.  
  327. {
  328.     Handle    rsrcData;
  329.     Str255    tempStr;
  330.     char        stageChar;
  331.  
  332.     short    major;                    // version info copied from 'vers' resource
  333.     short    minor;
  334.     short    minuscule;
  335.     short    release;
  336.     short    region;
  337.     enum {
  338.         kDevelopmentVersion =    0x20, 
  339.         kAlphaVersion =        0x40, 
  340.         kBetaVersion =            0x60, 
  341.         kFinalVersion =            0x80
  342.     }        stage;
  343.  
  344.  
  345.     // grab the resource & interpret it
  346.  
  347.     rsrcData = GetResource('vers', versID);
  348.     FailNILRes(rsrcData);
  349.  
  350.  
  351.     // thanks to Andrew Gilmartin for the code to read the resource
  352.  
  353.     major = HiNibble((*rsrcData)[0]) * 10 + LoNibble((*rsrcData)[0]);
  354.     minor = HiNibble((*rsrcData)[1]);
  355.     minuscule = LoNibble((*rsrcData)[1]);
  356.     
  357.     stage = (*rsrcData)[2];    
  358.     release = HiNibble((*rsrcData)[3]) * 10 + LoNibble((*rsrcData)[3]);
  359.     region = *(short*) ((*rsrcData) + 4);
  360.     
  361.         // ignore version strings
  362.     
  363.     ReleaseResource(rsrcData);
  364.  
  365.  
  366.     // convert version information above into textual format
  367.     
  368.     NumToString(major, theString);
  369.     theString[++theString[0]] = '.';                // sorry for the hard-wiring
  370.     NumToString(minor, tempStr);
  371.     ConcatPStrings(theString, tempStr);
  372.     if (minuscule) {
  373.         theString[++theString[0]] = '.';    
  374.         NumToString(minuscule, tempStr);
  375.         ConcatPStrings(theString, tempStr);
  376.     }
  377.     switch (stage) {
  378.         case kDevelopmentVersion:
  379.             stageChar = 'd';
  380.             break;
  381.         case kAlphaVersion:
  382.             stageChar = 'a';
  383.             break;
  384.         case kBetaVersion:
  385.             stageChar = 'b';
  386.             break;
  387.         case kFinalVersion:
  388.             stageChar = 'v';                // version naming, Claris-style…why not?
  389.             break;
  390.         default:
  391.             stageChar = '?';
  392.     }
  393.     if (release) {
  394.         theString[++theString[0]] = stageChar;
  395.         NumToString(release, tempStr);
  396.         ConcatPStrings(theString, tempStr);
  397.     }
  398.  
  399. }
  400.